package com.briup.Client.gather.Impl;

import com.briup.Client.gather.Gather;
import com.briup.Config.BeanAware;
import com.briup.Config.Impl.SmartConfigImpl;
import com.briup.Config.PropertiesAware;
import com.briup.Config.SmartConfig;
import com.briup.Logger.Impl.LogImpl;
import com.briup.Logger.Log;
import com.briup.entity.Environment;
import org.apache.log4j.Logger;

import java.io.*;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class GatherBackupImpl implements Gather , BeanAware , PropertiesAware {
    //private Log log = new LogImpl();
    //private Logger log= Logger.getLogger("com.briup.Client.gather.Impl.GatherBackupImpl");
    private Log log;

    //采集数据文件
    private String gatherFilePath;

    //采集模块备份文件
    //private File backupFile = new File("D:\\training2\\idea_code\\Smart\\src\\main\\resources\\gather.backup");
    private String gatherBackupFilePath;

    @Override
    public Collection<Environment> gather() {
        //声明随机访问流
        RandomAccessFile raf = null;
        //声明数据字节输入流
        DataInputStream dis = null;
        //声明数据字节输出流
        DataOutputStream dos = null;

        //记录偏移量
        long offset = 0L;
        //定义List集合
        List<Environment> environments = new ArrayList<>();

        //数据源文件
        //File dataFile = new File("D:\\training2\\idea_code\\Smart\\src\\main\\resources\\data-dev");
        File dataFile = new File(gatherFilePath);
        File backupFile = new File(gatherBackupFilePath);

        if (backupFile.exists() && backupFile.isFile() && backupFile.length() > 0) {
            log.info("备份文件存在并且存放内容");
            try {
                //创建流
                dis = new DataInputStream(new FileInputStream(backupFile));
                //使用流(上一次采集数据的偏移量【字节】)
                offset = dis.readLong();
                //换行（偏移量自增2）
                offset += 2;
            } catch (Exception e) {
               log.error("备份文件写入失败！");
            }
        }
        try {
            //创建随机访问流
            raf = new RandomAccessFile(dataFile.getAbsoluteFile(),"r");
            //跳过指定偏移量
            raf.seek(offset);
            //正常采集
            log.info("开始采集数据.....");
            // 标识  记录一整行数据
            String line =null;
            //读取数据
            while ((line = raf.readLine()) != null){
                /**
                 * line记录一整行数据
                 * 100|101|2|16|1|3|5d606f7802|1|1516323596029
                 */
                //按照 | 进行分割
                String[] data = line.split("[|]");
                //创建Environment对象
                Environment environment = new Environment();
                //为发送端ID赋值
                environment.setSrcId(data[0]);
                //为树莓派系统ID赋值
                environment.setDesId(data[1]);
                //为区域模块ID赋值
                environment.setDevId(data[2]);
                //为传感器个数进行赋值
                environment.setCount(Integer.parseInt(data[4]));
                //为指令标号进行赋值
                environment.setCmd(data[5]);
                //为状态标识赋值
                environment.setStatus(Integer.parseInt(data[7]));
                //为采集时间赋值
                environment.setGather_date(new Timestamp(Long.parseLong(data[8])));
                if ("16".equals(data[3])){
                    Environment humidityEnvironment = copyEnvironmentObject(environment);
                    environment.setName("温度");
                    environment.setSensorAddress(data[3]);
                    //1.截取字符串
                    String substring = data[6].substring(0, 4);
                    //2.转换成10进制
                    int i = Integer.parseInt(substring, 16);
                    //3.运算
                    float f = (i*(0.00268127F))-46.85F;
                    environment.setData(f);
                    //添加到集合
                    environments.add(environment);
                    humidityEnvironment.setName("湿度");
                    humidityEnvironment.setSensorAddress(data[3]);

                    //1.截取字符串
                    String humiditySubstring = data[6].substring(4, 8);
                    //2.转换成10进制
                    int j = Integer.parseInt(humiditySubstring, 16);
                    //3.运算
                    float  humidity = (j*0.00190735F)-6;
                    humidityEnvironment.setData(humidity);
                    //添加到集合
                    environments.add(humidityEnvironment);
                }else if ("256".equals(data[3])){
                    //光照强度
                    //采集数据名称赋值
                    environment.setName("光照强度");
                    //传感器地址赋值
                    environment.setSensorAddress(data[3]);
                    //数据赋值    5d606f7802
                    //1. 截取字符串 0 4
                    //2. 转换成10进制
                    //隐式转换
                    environment.setData(Integer.parseInt(data[6].substring(0, 4), 16));
                    //添加到集合
                    environments.add(environment);
                }else {
                    //二氧化碳浓度  1280
                    //采集数据名称赋值
                    environment.setName("二氧化碳浓度");
                    //传感器地址赋值
                    environment.setSensorAddress(data[3]);
                    //数据赋值    5d606f7802
                    environment.setData(Integer.parseInt(data[6].substring(0,4),16));
                    //添加到集合
                    environments.add(environment);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }finally {
            try {
                //创建数据字节输出流
                dos = new DataOutputStream(new FileOutputStream(backupFile));

                //写新的偏移量
                long filePointer = raf.getFilePointer();

                //将新的偏移量写入到备份文件
                dos.writeLong(filePointer);
                log.info("备份数据写入成功，采集模块完成.....");

                //关闭资源
                if (dos != null) {
                    dos.close();
                }
                if (raf != null) {
                    raf.close();
                }
                if (dis != null){
                    dis.close();
                }
            } catch (Exception e) {
                log.error("采集备份文件写入失败.....");
            }
        }
        return environments;
    }
    /**
     * 将温度环境对象拷贝属性给湿度环境对象，并返回湿度环境对象
     * @param temperatureEnvironment  温度环境对象
     * @return 湿度环境对象
     */
    private Environment copyEnvironmentObject(Environment temperatureEnvironment){
        return new Environment(null,temperatureEnvironment.getSrcId(),temperatureEnvironment.getDesId(),temperatureEnvironment.getDevId(),null,temperatureEnvironment.getCount(),temperatureEnvironment.getCmd(),0.0f,temperatureEnvironment.getStatus(),temperatureEnvironment.getGather_date());
    }

    @Override
    public void setBean(SmartConfig smartConfig) {
        //为log赋值
        log=smartConfig.getLogger();
    }

    @Override
    public void setProperties() {
        gatherFilePath = (String) SmartConfigImpl.getPropertiesMap().get("gatherFilePath");
        gatherBackupFilePath = (String) SmartConfigImpl.getPropertiesMap().get("gatherBackupFilePath");

    }
}
